package framework.pid;

import framework.order.OrderNumUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * PID工具
 */
public class PidUtil {

    /**
     * 构建树
     *
     * @param list
     * @param desc
     * @param topLevel
     * @param <T>
     * @return
     */
    public static <T extends PidOption> List<T> tree(List<T> list, String topLevel, boolean desc) {

        //
        OrderNumUtil.order(list, desc);

        //
        Map<String, PidOption> map = new HashMap<>();
        List<T> optionList = new ArrayList<>();
        List<T> tops = new ArrayList<>();
        //top menu
        for (T option : list) {
            optionList.add(option);
            if (option.pid() == null || topLevel.equals(option.pid())) {
                tops.add(option);
            }
            map.put(option.id(), option);
        }
        //children menu
        for (T option : optionList) {
            if (option.pid() != null && !topLevel.equals(option.pid())) {
                PidOption parent = map.get(option.pid());
                if (parent != null) {
                    parent.getChildren().add(option);
                }
            }
        }

        //
        return tops;
    }

    /**
     * 清除零子节点的树
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T extends PidOption> void cleanNonChildren(List<T> list) {
        for (int i = list.size() - 1; i >= 0; i--) {
            T t = list.get(i);
            if (t.getChildren().size() > 0) {
                cleanNonChildren(t.getChildren());
            } else {
                list.remove(i);
            }
        }
    }

    /**
     * 清除符合条件的节点
     *
     * @param list
     * @param matcher
     * @param <T>
     * @return
     */
    public static <T extends PidOption> void cleanNonChildren(List<T> list, Function<T, Boolean> matcher) {
        for (int i = list.size() - 1; i >= 0; i--) {
            T t = list.get(i);
            if (matcher.apply(t)) {
                list.remove(i);
            } else {
                List<T> children = (List<T>) t.getChildren();
                cleanNonChildren(children, matcher);
            }
        }
    }
}
